﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection.Emit;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace BYUStock
{
    public partial class BkHome : Form
    {
        string API;
        string UriBkHome;
        const string API_SOHU = "SOHU";
        const string UriBkHome_SOHU = "https://q.stock.sohu.com/cn/bk.shtml";

        public BkHome()
        {
            InitializeComponent();
            API = API_SOHU;
            UriBkHome = UriBkHome_SOHU;
        }

        private void BkHome_Load(object sender, EventArgs e)
        {
            InitBrower();

            int bkFails = 0;
            var bkSuccs = RefreshBkList(out bkFails);
            MessageBox.Show($"板块列表更新成功：{bkSuccs}，板块列表更新失败：{bkFails}");

            int stockFails = 0;
            int stockSuccs = 0;
            var localPath = AppDomain.CurrentDomain.BaseDirectory + $@"BK\";
            var date = "" + DateTime.Now.Year + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0');
            var localFile = $@"{localPath}{date}.html";
            string err;
            if (LoadLocalBks(localFile, out err))
            {
                var connStr = "Data Source =" + AppDomain.CurrentDomain.BaseDirectory + "stock_base.db;";
                using (var conn = new SQLiteConnection(connStr))
                {
                    using (var cmd = new SQLiteCommand())
                    {
                        conn.Open();
                        cmd.Connection = conn;
                        foreach (var item in Bks)
                        {
                            ///板块成分股导入防重
                            var bkCode = item.Key;
                            var sql1 = $@"select GroupID from StockGroup where ID = '{bkCode}';";
                            cmd.CommandText = sql1;
                            var exsit = cmd.ExecuteScalar();
                            if (exsit != null) continue;

                            string uriBk = null;
                            if (API == API_SOHU)
                            {
                                uriBk = $"https://q.stock.sohu.com/cn/{bkCode}.shtml";
                            }
                            var content = Global.DownloadHtmlContent(uriBk, "BkPages", bkCode);
                            var stocks = ParseStocksOfBk_SOHU(content);
                            foreach (var stock in stocks)
                            {
                                var stockCode = stock.Key;
                                var stockName = stock.Value;
                                var uid = bkCode + "_" + stockCode;
                                var sql2 = $@"select ID from StockGroup where ID = '{uid}';";
                                cmd.CommandText = sql2;
                                var exsit2 = cmd.ExecuteScalar();
                                if (exsit2 != null) continue;
                                var sql = $@"insert into StockGroup values('{uid}','{bkCode}','BYU','{stockCode}','{stockName}','{date}');";
                                cmd.CommandText = sql;
                                var result = cmd.ExecuteNonQuery();
                                if (result != 1)
                                {
                                    stockFails++;
                                }
                                else
                                {
                                    stockSuccs++;
                                }
                            }
                        }
                    }
                }
                MessageBox.Show($"板块成分更新成功：{bkSuccs}，板块成分更新失败：{bkFails}");
            }
        }

        void InitBrower()
        {
            this.Controls.Add(WBrower_BK);
            WBrower_BK.Dock = DockStyle.Fill;
            WBrower_BK.Show();
        }
        void ShowUrl(string uri)
        {
            WBrower_BK.Url = new Uri(uri);
            WBrower_BK.Refresh();
        }
        void ShowBkDetail(string bkCode, string api = API_SOHU)
        {
            string uriBk = null;
            if (api == API_SOHU)
            {
                uriBk = $"https://q.stock.sohu.com/cn/{bkCode}.shtml";
            }
            ShowUrl(uriBk);
        }

        WebClient Client = new WebClient();
        WebBrowser WBrower_BK = new WebBrowser();

        Dictionary<string, string> Bks = new Dictionary<string, string>();
        int RefreshBkList(out int updateFails)
        {
            var localPath = AppDomain.CurrentDomain.BaseDirectory + $@"BK\";
            var date = "" + DateTime.Now.Year + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0');
            WBrower_BK.Url = new Uri(UriBkHome);
            byte[] bytes = Client.DownloadData(UriBkHome);
            if (!Directory.Exists(localPath))
            {
                try
                {
                    Directory.CreateDirectory(localPath);
                }
                catch { }
            }
            File.WriteAllBytes($@"{localPath}{date}.html", bytes);
            string content = Encoding.GetEncoding("GB2312").GetString(bytes);
            Console.WriteLine(content);
            var matchs = Regex.Matches(content, @"bk_\d\d\d\d\D*<");
            var connStr = "Data Source =" + AppDomain.CurrentDomain.BaseDirectory + "stock_base.db;";
            using (var conn = new SQLiteConnection(connStr))
            {
                conn.Open();
                using (var cmd = new SQLiteCommand())
                {
                    cmd.Connection = conn;
                    updateFails = 0;
                    int updateSuccs = 0;
                    foreach (Match match in matchs)
                    {
                        var subs = match.Value.Split('.');
                        var bkCode = subs[0];
                        var bkName = subs[1].Substring(23).Split('<')[0];
                        if (!Bks.ContainsKey(bkCode))
                        {
                            Bks.Add(bkCode, bkName);
                            var sql1 = $@"select ID from GroupKind where ID = '{bkCode}';";
                            cmd.CommandText = sql1;
                            var exsit = cmd.ExecuteScalar();
                            if (exsit == null)
                            {
                                var sql = $@"insert into GroupKind values('{bkCode}','{bkName}','BYU',0,{date});";
                                cmd.CommandText = sql;
                                var result = cmd.ExecuteNonQuery();
                                if (result != 1)
                                {
                                    updateFails++;
                                }
                                else
                                {
                                    updateSuccs++;
                                }
                            }
                        }
                    }
                    return updateSuccs;
                }
            }
        }
        bool LoadLocalBks(string localFile, out string err)
        {
            try
            {
                var bytes = File.ReadAllBytes(localFile);
                string content = Encoding.GetEncoding("GB2312").GetString(bytes);
                Console.WriteLine(content);
                var matchs = Regex.Matches(content, @"bk_\d\d\d\d\D*<");
                foreach (Match match in matchs)
                {
                    var subs = match.Value.Split('.');
                    var bkCode = subs[0];
                    var bkName = subs[1].Substring(23).Split('<')[0];
                    if (!Bks.ContainsKey(bkCode))
                    {
                        Bks.Add(bkCode, bkName);
                    }
                }
                err = null;
                return true;
            }
            catch (Exception ex)
            {
                err = ex.Message;
                return false;
            }
        }
        Dictionary<string, string> ParseStocksOfBk_SOHU(string content)
        {
            var result = new Dictionary<string, string>();
            var matchs = Regex.Matches(content, @"cn/\d\d\d\d\d\d\S*\starget=\S*</a>");
            foreach (Match match in matchs)
            {
                var subs = match.Value.Split('=');
                var stockCode = subs[0].Substring(3, 6);
                var stockName = subs[1].Split('<')[0].Substring(9);
                result.Add(stockCode, stockName);
            }
            return result;
        }
    }
}
